package cn.iocoder.yudao.module.reading.service.audio;

import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.reading.controller.admin.audio.vo.*;
import cn.iocoder.yudao.module.reading.dal.dataobject.audio.AudioResourceDO;
import cn.iocoder.yudao.module.reading.dal.dataobject.book.PictureBookDO;
import cn.iocoder.yudao.module.reading.dal.dataobject.bookset.BookSetDO;
import cn.iocoder.yudao.module.reading.dal.mysql.audio.AudioResourceMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.book.PictureBookMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.bookset.BookSetMapper;
import cn.iocoder.yudao.module.reading.framework.util.StaticResourceUrlUtils;
import cn.iocoder.yudao.module.reading.enums.ErrorCodeConstants;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

/**
 * 音频资源管理 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class AudioResourceServiceImpl implements AudioResourceService {

    @Resource
    private AudioResourceMapper audioResourceMapper;

    @Resource
    private BookSetMapper bookSetMapper;

    @Resource
    private PictureBookMapper pictureBookMapper;

    @Resource
    private StaticResourceUrlUtils staticResourceUrlUtils;

    @Override
    @Transactional
    public Long createAudioResource(AudioResourceCreateReqVO createReqVO) {
        // 校验绘本集和绘本是否存在
        validateBookSetAndBook(createReqVO.getBookSetId(), createReqVO.getBookId());

        // 如果没有指定绘本集，自动设置为绘本所属的绘本集
        if (createReqVO.getBookSetId() == null && createReqVO.getBookId() != null) {
            PictureBookDO book = pictureBookMapper.selectById(createReqVO.getBookId());
            if (book != null) {
                createReqVO.setBookSetId(book.getBookSetId());
            }
        }

        // 插入
        AudioResourceDO audioResource = BeanUtils.toBean(createReqVO, AudioResourceDO.class);

        // 将完整URL转换为相对路径存储
        audioResource.setAudioUrl(staticResourceUrlUtils.toRelativePath(audioResource.getAudioUrl()));
        audioResource.setCover(staticResourceUrlUtils.toRelativePath(audioResource.getCover()));

        // 设置默认值
        if (audioResource.getSortOrder() == null) {
            audioResource.setSortOrder(0);
        }
        if (audioResource.getEnabled() == null) {
            audioResource.setEnabled(true);
        }

        audioResourceMapper.insert(audioResource);

        log.info("创建音频资源成功，ID: {}, 标题: {}, 音频URL: {}, 封面URL: {}",
                audioResource.getId(), audioResource.getTitle(),
                audioResource.getAudioUrl(), audioResource.getCover());
        return audioResource.getId();
    }

    @Override
    @Transactional
    public void updateAudioResource(AudioResourceUpdateReqVO updateReqVO) {
        // 校验存在
        validateAudioResourceExists(updateReqVO.getId());

        // 校验绘本集和绘本是否存在
        validateBookSetAndBook(updateReqVO.getBookSetId(), updateReqVO.getBookId());

        // 如果没有指定绘本集，自动设置为绘本所属的绘本集
        if (updateReqVO.getBookSetId() == null && updateReqVO.getBookId() != null) {
            PictureBookDO book = pictureBookMapper.selectById(updateReqVO.getBookId());
            if (book != null) {
                updateReqVO.setBookSetId(book.getBookSetId());
            }
        }

        // 更新
        AudioResourceDO updateObj = BeanUtils.toBean(updateReqVO, AudioResourceDO.class);

        // 将完整URL转换为相对路径存储
        updateObj.setAudioUrl(staticResourceUrlUtils.toRelativePath(updateObj.getAudioUrl()));
        updateObj.setCover(staticResourceUrlUtils.toRelativePath(updateObj.getCover()));

        audioResourceMapper.updateById(updateObj);

        log.info("更新音频资源成功，ID: {}, 标题: {}, 音频URL: {}, 封面URL: {}",
                updateObj.getId(), updateObj.getTitle(),
                updateObj.getAudioUrl(), updateObj.getCover());
    }

    @Override
    @Transactional
    public void deleteAudioResource(Long id) {
        // 校验存在
        validateAudioResourceExists(id);
        
        // 删除
        audioResourceMapper.deleteById(id);
        
        log.info("删除音频资源成功，ID: {}", id);
    }

    @Override
    public AudioResourceDO getAudioResource(Long id) {
        return audioResourceMapper.selectById(id);
    }

    @Override
    public PageResult<AudioResourceDO> getAudioResourcePage(AudioResourcePageReqVO pageReqVO) {
        return audioResourceMapper.selectPage(pageReqVO);
    }

    @Override
    public List<AudioResourceDO> getAudioResourceList(AudioResourceListReqVO listReqVO) {
        return audioResourceMapper.selectList(listReqVO);
    }

    @Override
    @Transactional
    public void batchUpdateAudioResourceStatus(List<Long> ids, Boolean enabled) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        
        // 校验音频资源存在
        for (Long id : ids) {
            validateAudioResourceExists(id);
        }
        
        // 批量更新状态
        audioResourceMapper.updateBatchStatus(ids, enabled);
        
        log.info("批量更新音频资源状态成功，IDs: {}, 状态: {}", ids, enabled);
    }

    @Override
    @Transactional
    public void batchDeleteAudioResource(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        
        // 校验音频资源存在
        for (Long id : ids) {
            validateAudioResourceExists(id);
        }
        
        // 批量删除
        audioResourceMapper.deleteBatchIds(ids);
        
        log.info("批量删除音频资源成功，IDs: {}", ids);
    }

    @Override
    @Transactional
    public void updateAudioResourceSortOrder(Long id, Integer sortOrder) {
        // 校验存在
        validateAudioResourceExists(id);
        
        // 更新排序
        AudioResourceDO updateObj = new AudioResourceDO();
        updateObj.setId(id);
        updateObj.setSortOrder(sortOrder);
        audioResourceMapper.updateById(updateObj);
        
        log.info("更新音频资源排序成功，ID: {}, 排序: {}", id, sortOrder);
    }

    @Override
    public List<String> getAudioCategories() {
        return Arrays.asList("recent", "english", "chinese", "favorite");
    }

    @Override
    public List<String> getAudioLanguages() {
        return Arrays.asList("en", "zh", "bilingual");
    }

    @Override
    public void validateAudioResourceExists(Long id) {
        if (audioResourceMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.AUDIO_RESOURCE_NOT_EXISTS);
        }
    }

    /**
     * 校验绘本集和绘本是否存在
     */
    private void validateBookSetAndBook(Long bookSetId, Long bookId) {
        // 音频必须绑定到具体的绘本
        if (bookId == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.AUDIO_MUST_BIND_TO_BOOK);
        }

        PictureBookDO book = pictureBookMapper.selectById(bookId);
        if (book == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.PICTURE_BOOK_NOT_EXISTS);
        }

        // 如果指定了绘本集，需要校验绘本是否属于该绘本集
        if (bookSetId != null && !bookSetId.equals(book.getBookSetId())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.BOOK_NOT_BELONG_TO_BOOK_SET);
        }

        // 如果没有指定绘本集，自动设置为绘本所属的绘本集
        if (bookSetId == null) {
            // 这里需要在调用方处理，因为我们需要修改请求对象
        }
    }
}
